package com.teacher.game.framework.animation;

import com.teacher.game.framework.util.Painter;

/**
 * 动画管理器 - 负责多帧动画的播放和管理
 * 支持循环播放、时间驱动的帧切换
 */
public class Animation {

    private Frame frames[];
    private double frameEndTimes[];
    private int currentFrameIndex = 0;

    private double currentTime;
    private double totalDuration;

    /**
     * 构造函数 - 创建动画序列
     * @param frames 动画帧数组（可变参数）
     */
    public Animation(Frame... frames) {
        this.frames = frames;
        frameEndTimes = new double[frames.length];
        for (int i = 0; i < frames.length; i++) {
            totalDuration += frames[i].getDuration();
            frameEndTimes[i] = totalDuration;
        }
    }

    /**
     * 更新动画状态 - 根据时间增量推进动画
     * @param deltaTime 时间增量（秒）
     */
    public synchronized void update(double deltaTime) {
        currentTime += deltaTime;
        if (currentTime > totalDuration) {
            wrapAnimation();
        }
        while (currentTime > frameEndTimes[currentFrameIndex]) {
            currentFrameIndex++;
        }
    }

    /**
     * 动画循环包装 - 当动画播放完成后重新开始
     */
    private void wrapAnimation() {
        currentTime %= totalDuration;
        currentFrameIndex = 0;
    }

    /**
     * 渲染当前动画帧
     * @param g 绘制工具
     * @param x X坐标
     * @param y Y坐标
     */
    public synchronized void render(Painter g, int x, int y) {
        g.drawImage(frames[currentFrameIndex].getImage(), x, y);
    }

    /**
     * 渲染当前动画帧（指定尺寸）
     * @param g 绘制工具
     * @param x X坐标
     * @param y Y坐标
     * @param w 宽度
     * @param h 高度
     */
    public synchronized void render(Painter g, int x, int y, int w, int h) {
        g.drawImage(frames[currentFrameIndex].getImage(), x, y, w, h);
    }

    /**
     * 获取当前帧
     * @return 当前动画帧
     */
    public Frame getCurrentFrame() {
        return frames[currentFrameIndex];
    }

    /**
     * 获取动画总时长
     * @return 总时长（秒）
     */
    public double getTotalDuration() {
        return totalDuration;
    }

    /**
     * 重置动画到第一帧
     */
    public void reset() {
        currentTime = 0;
        currentFrameIndex = 0;
    }
}